`timescale 1ns / 1ps
/******************************************************************************
*                                                                             *
* UTICA softcore v0.1                                                         *
*                                                                             *
* Copyright (c) 2012 Andrew D. Zonenberg                                      *
* All rights reserved.                                                        *
*                                                                             *
* Redistribution and use in source and binary forms, with or without modifi-  *
* cation, are permitted provided that the following conditions are met:       *
*                                                                             *
*    * Redistributions of source code must retain the above copyright notice  *
*      this list of conditions and the following disclaimer.                  *
*                                                                             *
*    * Redistributions in binary form must reproduce the above copyright      *
*      notice, this list of conditions and the following disclaimer in the    *
*      documentation and/or other materials provided with the distribution.   *
*                                                                             *
*    * Neither the name of the author nor the names of any contributors may be*
*      used to endorse or promote products derived from this software without *
*      specific prior written permission.                                     *
*                                                                             *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN     *
* NO EVENT SHALL THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT,         *
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    *
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,   *
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY       *
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT         *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF    *
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.           *
*                                                                             *
******************************************************************************/

/**
	@file HardwareTestbench_NANDFlashController.v
	@author Andrew D. Zonenberg
	@brief Top-level module for testing NAND flash controller
 */
module HardwareTestbench_NANDFlashController(
	clk_20mhz,
	onfi_ale, onfi_ce_n, onfi_cle, onfi_re_n, onfi_we_n, onfi_wp_n, onfi_io, onfi_busy_n,
	leds, buttons,
	uart_tx, uart_rx
    );

	////////////////////////////////////////////////////////////////////////////////////////////////
	// IO declarations
	input wire clk_20mhz;
	
	output wire onfi_ale;
	output wire onfi_ce_n;
	output wire onfi_cle;
	output wire onfi_re_n;
	output wire onfi_we_n;
	output wire onfi_wp_n;
	inout wire[7:0] onfi_io;
	input wire onfi_busy_n;
	
	output wire[7:0] leds;
	
	input wire[3:0] buttons;
	
	input wire uart_rx;
	output wire uart_tx;
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Clock management
	wire clk;
	wire main_clk_pll_reset;
	wire main_clk_pll_locked;
	
	//TODO: real reset here!
	assign main_clk_pll_reset = 0;
	
	CoreClockManagement clkmgr (
		.clk_20mhz(clk_20mhz), 
		.clk(clk), 
		.main_clk_pll_reset(main_clk_pll_reset), 
		.main_clk_pll_locked(main_clk_pll_locked)
		);
		
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Generate a nice slow debouncing clock
	reg clk_slow_edge = 0;							//asserted for one clk cycle every 2^16 cycles (roughly 1 KHz at 80 MHz)
	reg[15:0] clkdiv = 0;
	always @(posedge clk) begin
		clkdiv <= clkdiv + 1;
		clk_slow_edge <= 0;
		if(clkdiv == 0)
			clk_slow_edge <= 1;
	end
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	// Debounce the buttons
	
	wire[3:0] buttons_debounced;
	
	SwitchDebouncer #(.INIT_VAL(0)) btn0 (.clk(clk), .clken(clk_slow_edge), .din(buttons[0]), .dout(buttons_debounced[0]));
	SwitchDebouncer #(.INIT_VAL(0)) btn1 (.clk(clk), .clken(clk_slow_edge), .din(buttons[1]), .dout(buttons_debounced[1]));
	SwitchDebouncer #(.INIT_VAL(0)) btn2 (.clk(clk), .clken(clk_slow_edge), .din(buttons[2]), .dout(buttons_debounced[2]));
	SwitchDebouncer #(.INIT_VAL(0)) btn3 (.clk(clk), .clken(clk_slow_edge), .din(buttons[3]), .dout(buttons_debounced[3]));

	////////////////////////////////////////////////////////////////////////////////////////////////
	// The actual flash controller
	
	NANDFlashController controller (
		.clk(clk), 
		.onfi_ale(onfi_ale), 
		.onfi_ce_n(onfi_ce_n), 
		.onfi_cle(onfi_cle), 
		.onfi_re_n(onfi_re_n), 
		.onfi_we_n(onfi_we_n), 
		.onfi_wp_n(onfi_wp_n), 
		.onfi_io(onfi_io), 
		.onfi_busy_n(onfi_busy_n), 
		.start(buttons[0]), 
		.leds(leds),
		.uart_tx(uart_tx),
		.uart_rx(uart_rx)
		);

endmodule
